/*
 * Lenovo Group
 * Copyright (c) 2015-2016 All Rights Reserved.
 * 
 * Project Name:assign-tracer
 * Create Time: 2016年1月21日 下午4:19:48
 */
package com.lenovo.lmrp.server.assigntracer.util.pusher;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lenovo.lmrp.api.constant.MessageTemplateType;
import com.lenovo.lmrp.api.constant.SendType;
import com.lenovo.lmrp.api.model.entity.MessageTemplatePO;
import com.lenovo.lmrp.api.model.entity.TicketPO;
import com.lenovo.lmrp.api.model.view.EngineerVO;
import com.lenovo.lmrp.server.assigntracer.util.cache.AssignTracerCache;
import com.lenovo.lmrp.server.assigntracer.util.cache.CacheObj;
import com.lenovo.sdc.framework.cache.CacheItem;
import com.lenovo.sdc.framework.util.AttributeBean;
import com.lenovo.sdc.framework.util.CommonUtil;

/**
 * @author songyz
 * 
 */
public class SenderUtil {
	private static GeTuiSender geTuiSender;
	private static SMSSender smsSender;
	private static EmailSender emailSender;
	private final static Logger logger = LoggerFactory.getLogger(SenderUtil.class);

	// 多线程池
	private static ExecutorService es;

	@Inject
	public static void set(AttributeBean params) {
		es = new ThreadPoolExecutor(4,
				Runtime.getRuntime().availableProcessors() * 2,
				30, TimeUnit.MINUTES,
				new LinkedBlockingQueue<Runnable>());
		if (es != null) {
			logger.info("ExecutorService is successed initialize");
		}
	}

	@Inject
	public static void set(GeTuiSender geTuiSender) {
		SenderUtil.geTuiSender = geTuiSender;
	}

	@Inject
	public static void set(SMSSender smsSender) {
		SenderUtil.smsSender = smsSender;
	}

	@Inject
	public static void set(EmailSender emailSender) {
		SenderUtil.emailSender = emailSender;
	}

	/**
	 * @param msParameter
	 * @return
	 */
	public static void senderMessage(List<PushParameter> msParameters) {
		for (PushParameter pushParameter : msParameters) {
			switch (pushParameter.getSendType()) {
			case GETUI:
				es.execute(geTuiSender.addMessageToList(pushParameter));
				break;
			case SMS:
				es.execute(smsSender.addMessageToList(pushParameter));
				break;
			case EMAIL:
				es.execute(emailSender.addMessageToList(pushParameter));
				break;
			case WEICHART:
				break;
			}
		}
	}

	/**
	 * 使用消息模板发送消息,并且使用缓存记录发送记录
	 * 
	 * @param engineerVO
	 *            工程师
	 * @param messageTemplateList
	 *            消息模板列表
	 */
	public static void sendMessageCreateCache(EngineerVO engineerVO, List<MessageTemplatePO> messageTemplateList) {
		sendMessageByMessageTemplate(engineerVO, messageTemplateList, false, null);
	}

	/**
	 * 使用消息模板发送消息,由于是重新发送，不创建新的记录缓存对象
	 * 
	 * @param engineerVO
	 *            工程师
	 * @param messageTemplateList
	 *            消息模板列表
	 * @param uuId
	 *            第一次发送失败的缓存记录的key
	 */
	public static void sendMessageNotCreateCache(EngineerVO engineerVO, List<MessageTemplatePO> messageTemplateList,
			String uuId) {
		sendMessageByMessageTemplate(engineerVO, messageTemplateList, false, uuId);
	}

	/**
	 * 使用消息模板发送消息,不使用缓存记录发送记录
	 * 
	 * @param engineerVO
	 *            工程师
	 * @param messageTemplateList
	 *            消息模板列表
	 * @param uuId
	 *            第一次发送失败的缓存记录的key
	 */
	public static void sendMessageNotCreateCache(EngineerVO engineerVO, List<MessageTemplatePO> messageTemplateList) {
		sendMessageByMessageTemplate(engineerVO, messageTemplateList, false, null);
	}

	private static void sendMessageByMessageTemplate(EngineerVO engineerVO, List<MessageTemplatePO> messageTemplateList,
			boolean insertToCache, String uuId) {
		// FIXME 消息模板还未定义，后期需要修改
		List<PushParameter> pushParamList = new ArrayList<>();
		// @param insertToCache 是否需要将发送记录存入缓存（发送失败时，重试参数）
		// @param uuId 当需要使用缓存记录发送记录时，uuId参数不设置；当不需要使用缓存记录发送记录时，uuId参数必须设置
		String uuid = insertToCache == true || Objects.isNull(uuId) ? UUID.randomUUID().toString() : uuId;

		for (MessageTemplatePO messageTemplate : messageTemplateList) {
			// 消息模板 String filepath = messageTemplate.getFilepath();
			String title = "消息标题";
			String desc = "消息描述";
			String content = "消息主题";
			StringBuilder smsContent = new StringBuilder();
			switch (MessageTemplateType.getMessageTemplateType(messageTemplate.getMessagetype())) {
			case RESPECTS:// 0 - 问候,
				title = "问候";
				desc = "你好";
				content = "消息主题，你好";
				break;
			case GRAB:// 1 - 抢单通知
				title = "抢单提醒";
				TicketPO ticketPO = (TicketPO) engineerVO.getContent();
				desc = "抢单提醒：[" + ticketPO.getId() + "][" + ticketPO.getCaption() + "]";
				content = "抢单提醒：[" + ticketPO.getId() + "][" + ticketPO.getCaption() + "]";
				smsContent.append("编号").append(ticketPO.getId()).append("的工单请尽快登陆APP抢单:\n");
				smsContent.append("项目:").append(ticketPO.getOthers().getAttributeBean().getAttribute("projectname", "")).append("\n");
				smsContent.append("地址:").append(ticketPO.getOthers().getAttributeBean().getAttribute("customeraddress", "")).append("\n");
				smsContent.append("故障:").append(ticketPO.getCaption()).append("\n");
				break;
			case DISPATCH:// 2 - 分派提醒,
				title = "派单提醒";
				ticketPO = (TicketPO) engineerVO.getContent();
				desc = "派单提醒：[" + ticketPO.getId() + "][" + ticketPO.getCaption() + "]";
				content = "派单提醒：[" + ticketPO.getId() + "][" + ticketPO.getCaption() + "]";
				smsContent.append("编号").append(ticketPO.getId()).append("的工单请尽快登陆APP接单:\n");
                smsContent.append("项目:").append(ticketPO.getOthers().getAttributeBean().getAttribute("projectname", "")).append("\n");
                smsContent.append("地址:").append(ticketPO.getOthers().getAttributeBean().getAttribute("customeraddress", "")).append("\n");
                smsContent.append("故障:").append(ticketPO.getCaption()).append("\n");
				break;
			case SLA_REMIND:// 3-SLA提醒,
				title = "SLA提醒";
				desc = "SLA提醒";
				content = "SLA提醒";
				break;
			case REMINDER:// 4-催单提醒,
				title = "催单提醒";
				ticketPO = (TicketPO) engineerVO.getContent();
				desc = "催单提醒：[" + ticketPO.getId() + "][" + ticketPO.getCaption() + "]";
				content = "催单提醒：[" + ticketPO.getId() + "][" + ticketPO.getCaption() + "]";
				break;
			case ITSM_REPAIRCHANGE_REMIND:// 5-ITSM工单变更通知，
				ticketPO = (TicketPO) engineerVO.getContent();
				title = "工单变更提醒";
				desc = ticketPO.getCaption();
				content = ticketPO.getId();
				break;
			case APP_NEWVERSION_REMIND:// 6 - APP新版本通知，
				title = "APP新版本通知";
				desc = "APP新版本通知";
				content = "APP新版本通知";
				break;
			case LOGOUT:// 7 - 登出通知
				title = "登出提醒";
				desc = "您在其他设备到登录";
				content = "你在其他设备登录，登出提示";
				break;
			default:
				break;
			}

			switch (SendType.getSendType(messageTemplate.getSendmode())) {
			case GETUI:// 个推
				if (Objects.nonNull(engineerVO.getEngineerOnLineCids())
						&& !"".equals(engineerVO.getEngineerOnLineCids().trim())) {
					pushParamList.add(new PushParameter(engineerVO.getEngineerid(), engineerVO.getItsmcode(), uuid,
							engineerVO.getEngineerOnLineCids(), title, content, desc,
							messageTemplate.getMessagetype()));
					if (insertToCache) {
						AssignTracerCache.getClient().put(new CacheItem<CacheObj>(uuid,
								new CacheObj(uuid, engineerVO, messageTemplateList), "assign_tracer_send_error", 10));
					}
				}
				break;
			case SMS:// 短信
				pushParamList.add(new PushParameter(engineerVO.getEngineerid(), engineerVO.getItsmcode(), uuid,
						engineerVO.getPhone(), CommonUtil.isNullOrEmpty(smsContent.toString()) ? content : smsContent.toString()));
				if (insertToCache) {
					AssignTracerCache.getClient().put(new CacheItem<CacheObj>(uuid,
							new CacheObj(uuid, engineerVO, messageTemplateList), "assign_tracer_send_error", 10));
				}
				break;
			case EMAIL:// 邮件
				pushParamList.add(new PushParameter(engineerVO.getEngineerid(), engineerVO.getItsmcode(), uuid,
						engineerVO.getEmail(), title, content));
				if (insertToCache) {
					AssignTracerCache.getClient().put(new CacheItem<CacheObj>(uuid,
							new CacheObj(uuid, engineerVO, messageTemplateList), "assign_tracer_send_error", 10));
				}
				break;
			case WEICHART:
				break;

			default:
				if (Objects.nonNull(engineerVO.getEngineerOnLineCids())
						&& !"".equals(engineerVO.getEngineerOnLineCids().trim())) {
					pushParamList.add(new PushParameter(engineerVO.getEngineerid(), engineerVO.getItsmcode(), uuid,
							engineerVO.getEngineerOnLineCids(), title, content, desc,
							messageTemplate.getMessagetype()));
					if (insertToCache) {
						AssignTracerCache.getClient().put(new CacheItem<CacheObj>(uuid,
								new CacheObj(uuid, engineerVO, messageTemplateList), "assign_tracer_send_error", 10));
					}
				}
				break;
			}
		}
		SenderUtil.senderMessage(pushParamList);
	}
}
